﻿using FlexFlow.Model;
using FlexFlow.Base.Interface;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Collections;

namespace FlexFlow.Runtime
{
    /// <summary>
    /// 表示工作流引擎的流程启动阶段
    /// </summary>
    public class WorkFlowEngine : ManagerBase
    {
        /// <summary>
        /// 获取或设置默认的工作流引擎实例
        /// </summary>
        public static WorkFlowEngine Default { get; set; }

        private NotificationCatalogFactory catInfoFactory = new NotificationCatalogFactory()
        {
            Sender = "流程流转",
            DefaultDescription = "流程处理通知",
            DefaultType = NotificationType.Info
        };

        /// <summary>
        /// 开始流程
        /// </summary>
        /// <param name="userId">请求开始流程的用户ID</param>
        /// <param name="procId">请求开始的流程</param>
        /// <param name="data">用来启动流程的数据</param>
        /// <returns>操作结果，其中Tag为启动流程的流程实例ID</returns>
        public OperateResult StartProcess(Guid userId, Guid procId, KeyValuePair<Guid, Object>[] data)
        {
            //创建引擎流转上下文
            ProcessFlowContext flowContenxt = new ProcessFlowContext(this.Components);
            //绑定用户ID与流程ID
            flowContenxt.UserId = userId;
            flowContenxt.CurrentProcessId = procId;

            Process proc = flowContenxt.CurrentProcess;      //根据ID取得流程定义实例
            if (proc == null) return new OperateResult() { ResultCode = 0x100101, Message = "要开始的流程ID不存在！" };
            //判断流程状态
            if (proc.State != ProcessState.Installed) return new OperateResult() { ResultCode = 0x100102, Message = "流程未成功安装，无法开始！" };

            User user = flowContenxt.User; //根据ID取得用户实例
            if (user == null) return new OperateResult() { ResultCode = 0x100103, Message = "用户不存在！" };

            //TODO:用户进入流程相关权限验证
            //----------------------------------------------------------
            OperateResult permissionCheckResult = PermissionManager.Default.CheckPermission(userId, SystemPermissions.ProcessEnterPermission, procId.ToString(), true);
            if (permissionCheckResult.ResultCode != 200)
                return new OperateResult() { ResultCode = 0x100104, Message = "权限验证失败：" + permissionCheckResult.Message, InnerResult = permissionCheckResult };
            if ((bool)permissionCheckResult.Tag == false)
                return new OperateResult() { ResultCode = 0x100105, Message = "你没有发起该流程的权限" };

            //流程数据验证
            OperateResult validateResult = this.VaildateProcessData(flowContenxt, data);
            if (validateResult.ResultCode != 200) return new OperateResult() { ResultCode = 0x100106, Message = "数据验证失败：" + validateResult.Message };

            ProcessInstance procIns = this.Components.ProcessInstanceProvider.Create();                //创建流程实例
            {
                procIns.Creator = userId;
                procIns.ProcessId = procId;
                procIns.EnterData = data;
            };
            Activity startAct = proc.Activitys.FirstOrDefault(m => m.Identity == proc.StartActivity); //取得流程开始节点
            if (startAct == null) return new OperateResult() { ResultCode = 0x100107, Message = "流程的起始节点不存在！" };
            bool isProcInsSaveSuccess = this.Components.ProcessInstanceProvider.Add(procIns);
            if (!isProcInsSaveSuccess) return new OperateResult() { ResultCode = 0x100108, Message = "流程实例保存失败！" };

            //将创建的流程实例与开始节点绑定到流转上下文
            flowContenxt.CurrentProcessInstance = procIns;
            //更新流程实例状态
            bool isUpdateStateSuccess = this.Components.ProcessInstanceProvider.UpdateState(procIns.Identity, ProcessInstanceState.Running);
            if (!isUpdateStateSuccess) return new OperateResult() { ResultCode = 0x100109, Message = "更新流程实例状态失败！" };

            //从开始节点启动流程的流转
            OperateResult enterStartActivityResult = EnterActivity(flowContenxt, startAct, data);
            if (enterStartActivityResult.ResultCode != 200)
            {
                return new OperateResult()
                {
                    ResultCode = 0x100110,
                    Message = "进入开始流程失败！",
                    InnerResult = enterStartActivityResult
                };
            }

            return OperateResult.SuccessResult(procIns.Identity);
        }
        /// <summary>
        /// 根据用户ID取得流程实例列表
        /// </summary>
        /// <param name="userId">
        /// 用户ID
        /// </param>
        /// <returns>
        /// 操作结果，其中Tag为取得的流程实例列表
        /// </returns>
        public OperateResult GetProcessInstancesByUID(Guid userId)
        {
            List<ProcessInstance> procInsList = this.Components.ProcessInstanceProvider.GetByUID(userId);
            List<dynamic> result = new List<dynamic>();
            foreach (var procIns in procInsList)
            {
                Process proc = this.Components.ProcessProvider.Get(procIns.ProcessId);
                User creator = this.Components.UserProvider.Get(procIns.Creator);
                Activity act = proc == null ? null : proc.Activitys.FirstOrDefault(m => m.Identity == procIns.CurrentActivityId);
                string tag = "";
                switch (procIns.State)
                {
                    case ProcessInstanceState.Initiated:
                        tag = "Default:已初始化";
                        break;
                    case ProcessInstanceState.Running:
                        tag = "Info:正在运行";
                        break;
                    case ProcessInstanceState.Active:
                        tag = "Info:已激活";
                        break;
                    case ProcessInstanceState.Suspended:
                        tag = "Default:已暂停";
                        break;
                    case ProcessInstanceState.Completed:
                        tag = "Success:已完成";
                        break;
                    case ProcessInstanceState.Terminated:
                        tag = "Danger:已中止:" + procIns.Tag;
                        break;
                    default:
                        break;
                }
                if (proc != null && creator != null && act != null)
                {
                    result.Add(new
                    {
                        id = procIns.Identity,
                        procName = proc.Name + "[" + proc.Version + "]",
                        creatorName = creator.Name,
                        tag = tag,
                        createTime = procIns.CreateTime.ToString(),
                        lastFlowTime = procIns.LastFlowTime.ToString(),
                        actName = act.Name
                    });
                }
            }
            return OperateResult.SuccessResult(result);
        }
        /// <summary>
        /// 取得指定用户可以发起的流程列表
        /// </summary>
        /// <param name="userId">
        /// 用户Id
        /// </param>
        /// <returns>
        /// 操作结果，其中tag为获取到的流程列表
        /// </returns>
        public OperateResult GetUserEnterableProcesses(Guid userId)
        {
            //取得所有已安装的流程的Id
            List<Guid> processIds = this.Components.ProcessProvider.GetAllID(ProcessState.Installed);
            //移除无权发起的流程
            foreach (var procId in processIds.ToArray())
            {
                OperateResult permissionCheckResult = PermissionManager.Default.CheckPermission(userId, SystemPermissions.ProcessEnterPermission, procId.ToString(), true);
                if (permissionCheckResult.ResultCode != 200 || (bool)permissionCheckResult.Tag == false)
                    processIds.Remove(procId);
            }
            List<dynamic> procs = new List<dynamic>();
            //取得所有流程实例
            foreach (var procId in processIds)
            {
                Process proc = this.Components.ProcessProvider.Get(procId);
                //返回基础信息
                if (proc != null)
                {
                    procs.Add(new
                    {
                        id = proc.Identity,
                        name = proc.Name
                    });
                }
            }
            return OperateResult.SuccessResult(procs);
        }
        /// <summary>
        /// 取得指定用户的任务列表
        /// </summary>
        /// <param name="userId">
        /// 用户Id
        /// </param>
        /// <returns>
        /// 取得的任务列表
        /// </returns>
        public OperateResult GetUserTasks(Guid userId)
        {
            var tskRes = WorkFlowTaskManager.Default.GetReciveTaskList(userId);
            if (tskRes.ResultCode != 200)
            {
                return tskRes;
            }
            List<WorkFlowTask> tskList = (List<WorkFlowTask>)tskRes.Tag;
            List<dynamic> result = new List<dynamic>();
            foreach (var tsk in tskList)
            {
                Process proc = this.Components.ProcessProvider.Get(tsk.CurrentProcess);
                Activity act = proc == null ? null : proc.Activitys.FirstOrDefault(m => m.Identity == tsk.CurrentActivity);
                User sender = this.Components.UserProvider.Get(tsk.Sender);
                string tag = "";
                switch (tsk.State)
                {
                    case WorkFlowTaskState.Created:
                        tag = "Default:已创建";
                        break;
                    case WorkFlowTaskState.Opened:
                        tag = "Info:已打开";
                        break;
                    case WorkFlowTaskState.Closed:
                        tag = "Danger:已关闭:" + tsk.Message;
                        break;
                    case WorkFlowTaskState.Processed:
                        tag = "Success:已处理";
                        break;
                    default:
                        break;
                }

                if (proc != null && act != null && sender != null)
                {
                    result.Add(new
                    {
                        id = tsk.Identity,
                        procName = proc.Name,
                        senderName = sender.Name,
                        actName = act.Name,
                        sendTime = tsk.SendTime.ToString(),
                        compTime = tsk.CompeletedTime.ToString(),
                        taskType = tsk.Type,
                        tag = tag
                    });
                }
            }
            return OperateResult.SuccessResult(result);
        }
        /// <summary>
        /// 取得指定流程实例的步骤列表
        /// </summary>
        /// <param name="procInsId">
        /// 流程实例Id
        /// </param>
        /// <returns>
        /// 操作结果
        /// </returns>
        public OperateResult GetProcessSetps(Guid procInsId)
        {
            return OperateResult.SuccessResult(this.Components.FlowSetpProvider.GetProcessInstanceSetps(procInsId));
        }
        /// <summary>
        /// 取得已经注册的应用程序列表
        /// </summary>
        /// <returns>
        /// 操作结果，其中Tag为取得的应用程序列表
        /// </returns>
        public OperateResult GetRegisteredApplications()
        {
            return OperateResult.SuccessResult(this.Components.ApplicationPool.GetRegisteredApplications());
        }
        /// <summary>
        /// 打开指定任务
        /// </summary>
        /// <param name="taskId">
        /// 任务ID
        /// </param>
        /// <returns>
        /// 操作结果，其中Tag为任务实例
        /// </returns>
        public OperateResult OpenTask(Guid taskId)
        {
            WorkFlowTask task = this.Components.WorkFlowTaskProvider.Get(taskId);
            if (task == null)
            {
                return new OperateResult()
                {
                    ResultCode = 0x101201,
                    Message = "指定ID对应的工作流任务不存在！"
                };
            }
            //更新任务状态
            if (task.State == WorkFlowTaskState.Created)
            {
                bool stateUpdateSucceed = this.Components.WorkFlowTaskProvider.UpdateState(taskId, WorkFlowTaskState.Opened);
                if (!stateUpdateSucceed) return new OperateResult() { ResultCode = 0x101202, Message = "更新任务状态失败！" };
            }
            return OperateResult.SuccessResult(task);
        }
        /// <summary>
        /// 提交任务
        /// </summary>
        /// <param name="userId">
        /// 要提交任务的用户Id
        /// </param>
        /// <param name="tskId">
        /// 要提交的任务Id
        /// </param>
        /// <param name="submitData">
        /// 任务提交的数据
        /// </param>
        /// <returns>
        /// 操作结果
        /// </returns>
        public OperateResult SubmitTask(Guid userId, Guid tskId, Dictionary<string, object> submitData)
        {
            WorkFlowTask tsk = this.Components.WorkFlowTaskProvider.Get(tskId);
            if (tsk == null)
            {
                return new OperateResult()
                {
                    ResultCode = 0x101101,
                    Message = "指定任务不存在！"
                };
            }
            if (!tsk.Reciver.Contains(userId.ToString()))
            {
                return new OperateResult()
                {
                    ResultCode = 0x101102,
                    Message = "不能提交不是分发给自己的任务"
                };
            }
            tsk.SubmitData = submitData;
            bool submitDataUpdateResult = this.Components.WorkFlowTaskProvider.UpdateSubmitData(tskId, submitData);
            if (!submitDataUpdateResult)
            {
                return new OperateResult()
                {
                    ResultCode = 0x101103,
                    Message = "更新任务提交数据失败"
                };
            }
            if (tsk.State != WorkFlowTaskState.Opened)
            {
                return new OperateResult()
                {
                    ResultCode = 0x100104,
                    Message = "任务尚未打开或者已被关闭，无法提交"
                };
            }
            //构建引擎流转上下文
            ProcessFlowContext flowContext = new ProcessFlowContext(userId,
                tsk.CurrentProcess,
                tsk.CurrentProcessInstance,
                tsk.CurrentActivity,
                tsk.CurrentActivityInstance,
                tsk.CurrentSetpId,
                this.Components);
            string removedItem = ""; //表示已经被移除的项目的提示文本
            if (flowContext.User == null) removedItem += "当前用户 ";
            if (flowContext.CurrentProcess == null) removedItem += "流程定义 ";
            if (flowContext.CurrentActivity == null) removedItem += "活动定义 ";
            if (flowContext.CurrentProcessInstance == null) removedItem += "流程实例 ";
            if (flowContext.CurrentActivityInstance == null) removedItem += "活动实例 ";
            if (flowContext.CurrentFlowSetp == null) removedItem += "流程步骤 ";
            if (removedItem != "")
            {
                return new OperateResult()
                {
                    ResultCode = 0x101105,
                    Message = "以下数据已经失效，无法提交任务：" + removedItem
                };
            }
            return this.SubmitTask(flowContext, tsk);
        }

        /// <summary>
        /// 记录步骤起始信息
        /// </summary>
        /// <param name="fromContext">
        /// 包含起始信息的流转上下文
        /// </param>
        /// <returns>
        /// 包含起始信息的步骤对象
        /// </returns>
        private void RecordFrom(ProcessFlowContext fromContext)
        {
            FlowSetp setp = fromContext.CurrentFlowSetp;
            setp.FromActivityId = fromContext.CurrentActivityId;
            setp.FromActivityInstanceId = fromContext.CurrentActivityInstanceId;
            setp.FromActivityName = fromContext.CurrentActivity.Name;
            setp.FromUser = fromContext.UserId;
            setp.FromUserName = fromContext.User.Name;
        }
        /// <summary>
        /// 记录步骤末尾信息
        /// </summary>
        /// <param name="toContext">
        /// 包含末尾信息的流程上下文
        /// </param>
        private void RecordTo(ProcessFlowContext toContext)
        {
            FlowSetp setp = toContext.CurrentFlowSetp;
            setp.ToActivityId = toContext.CurrentActivityId;
            setp.ToActivityInstanceId = toContext.CurrentActivityInstanceId;
            setp.ToActivityName = toContext.CurrentActivity.Name;
            setp.ToUser = toContext.UserId;
            setp.ToUserName = toContext.User.Name;
        }
        /// <summary>
        /// 验证流程数据
        /// </summary>
        /// <param name="flowContext">
        /// 流程流转上下文，该上下文中应至少包含CurrentProcess或者CurrentProcessId
        /// </param>
        /// <param name="data">进入流程时用户提交的数据</param>
        /// <returns>操作结果</returns>
        private OperateResult VaildateProcessData(ProcessFlowContext flowContext, KeyValuePair<Guid, Object>[] data)
        {
            Process proc = flowContext.CurrentProcess;
            //开始流程时未定义数据但是流程需要数据
            if (data == null && proc.DataSlots != null && proc.DataSlots.Count() > 0)
            {
                return new OperateResult() { ResultCode = 0x10801, Message = "流程起始数据不全，无法开始流程！" };
            }
            else
            {
                //流程开始不需要数据
                if (proc.DataSlots == null || proc.DataSlots.Count() == 0)
                {
                    return OperateResult.SuccessResult();
                }
                else
                {
                    //验证数据
                    foreach (var slot in proc.DataSlots)
                    {
                        var obj = data.FirstOrDefault(m => m.Key == slot.Identity);
                        if (obj.Value == null && slot.Required)
                        {
                            return new OperateResult() { ResultCode = 0x10802, Message = "请添加 " + slot.Name + "数据后执行操作！" };
                        }
                    }
                }
            }
            return OperateResult.SuccessResult();
        }
        /// <summary>
        /// 初始化活动进入数据
        /// </summary>
        /// <param name="flowContext">
        /// 当前流程上下文
        /// </param>
        /// <param name="initAct">
        /// 要初始化的活动实例
        /// </param>
        /// <param name="actExecData">
        /// 上一个活动执行产生的数据
        /// </param>
        /// <returns>
        /// 操作结果，其中Tag为取得的数据列表
        /// </returns>
        private OperateResult InitActivityEnterData(ProcessFlowContext flowContext, ActivityInstance initAct, KeyValuePair<Guid, Object>[] actExecData)
        {
            if (flowContext.CurrentActivity.DataSlots == null || flowContext.CurrentActivity.DataSlots.Length == 0)
            {
                return OperateResult.SuccessResult();
            }
            List<KeyValuePair<Guid, Object>> datas = new List<KeyValuePair<Guid, Object>>();

            IEnumerable<KeyValuePair<Guid, Object>> unionDatas = new KeyValuePair<Guid, Object>[] { };

            if (flowContext.CurrentProcessInstance.EnterData != null)
                unionDatas = unionDatas.Union(flowContext.CurrentProcessInstance.EnterData);
            if (actExecData != null)
                unionDatas = unionDatas.Union(actExecData);
            foreach (var slot in flowContext.CurrentActivity.DataSlots)
            {
                var val = unionDatas.FirstOrDefault(m => m.Key == slot.Identity);
                if (val.Value == null && slot.Required)
                {
                    return new OperateResult() { ResultCode = 0x100901, Message = "设置流程数据失败，数据 " + slot.Name + " 未指定。" };
                }
                datas.Add(val);
            }
            initAct.EnterData = datas.ToArray();
            return OperateResult.SuccessResult();
        }
        /// <summary>
        /// 进入指定活动
        /// </summary>
        /// <param name="flowContext">
        /// 引擎流转上下文
        /// </param>
        /// <param name="act">
        /// 要进入的活动实例
        /// </param>
        /// <param name="data">
        /// 活动进入数据
        /// </param>
        /// <param name="previousAct">
        /// 表示该活动的前一个活动实例
        /// </param>
        /// <returns>
        /// 操作结果，其中Tag为新创建的流程实例的ID
        /// </returns>
        private OperateResult EnterActivity(ProcessFlowContext flowContext, Activity act, KeyValuePair<Guid, Object>[] data, ActivityInstance previousAct = null)
        {
            //TODO:用户进入活动相关权限验证
            //-----------------------------------------------------------
            //绑定流程实例到流转上下文
            flowContext.CurrentActivity = act;

            ActivityInstance actIns = this.Components.ActivityInstanceProvider.Create();   //创建流程实例
            {
                actIns.EnterData = data;
                actIns.ProcessInstanceId = flowContext.CurrentProcessInstanceId;
                actIns.ActivetyId = act.Identity;
            };
            //初始化活动数据
            OperateResult actEnterDataInitRes = this.InitActivityEnterData(flowContext, actIns, data);
            if (actEnterDataInitRes.ResultCode != 200)
                return new OperateResult() { ResultCode = 0x100201, Message = "初始化活动数据失败：" + actEnterDataInitRes.Message };

            //保存活动实例
            bool isActSaveSuccess = this.Components.ActivityInstanceProvider.Add(actIns);
            if (!isActSaveSuccess) return new OperateResult() { ResultCode = 0x100201, Message = "活动实例保存失败！" };
            //绑定活动实例到上下文
            flowContext.CurrentActivityInstance = actIns;
            flowContext.CurrentProcessInstance.CurrentActivityId = actIns.Identity;

            //更新流程的当前活动
            bool isCurrentActUpdateSuccess =
                this.Components.ProcessInstanceProvider.UpdateCurrentActivity(
                flowContext.CurrentProcessInstance.Identity,
                act.Identity);

            if (!isCurrentActUpdateSuccess) return new OperateResult() { ResultCode = 0x100202, Message = "设定当前活动失败！" };

            //记录步骤
            if (previousAct != null)
            {
                this.RecordTo(flowContext);
                //保存步骤
                bool isUpdateSetpSuccess = this.Components.FlowSetpProvider.Update(flowContext.CurrentFlowSetp);
                if (!isUpdateSetpSuccess) return new OperateResult() { ResultCode = 0x100204, Message = "保存步骤失败！" };
            }

            //执行活动
            OperateResult executeActivityResult = ExecuteActivity(flowContext, previousAct);
            if (executeActivityResult.ResultCode != 200)
            {
                return new OperateResult() { ResultCode = 0x100205, Message = "活动执行失败！", InnerResult = executeActivityResult };
            }
            return OperateResult.SuccessResult(actIns.Identity);
        }
        /// <summary>
        /// 构造应用程序执行上下文
        /// </summary>
        /// <param name="flowContext">
        /// 引擎流转上下文
        /// </param>
        /// <param name="previousAct">
        /// 与上下文绑定的前一个活动实例
        /// </param>
        /// <returns>
        /// 构造的应用程序执行上下文
        /// </returns>
        private ApplicationInvokeContext CreateApplicationInvokeContext(ProcessFlowContext flowContext, ActivityInstance previousAct = null)
        {
            //构造应用程序执行上下文
            ApplicationInvokeContext context = new ApplicationInvokeContext()
            {
                CurrentActivityInstance = flowContext.CurrentActivityInstance,
                CurrentProcessInstance = flowContext.CurrentProcessInstance,
                ActivityOptions = flowContext.CurrentActivity.Options == null ? new KeyValuePair<string, string>[] { } : flowContext.CurrentActivity.Options.ToArray(),
                Operators = flowContext.CurrentActivity.Operators == null ? null : flowContext.CurrentActivity.Operators
                                    .Split(',').Select(m => new Guid(m)).ToArray(),
                NextPaths = flowContext.CurrentProcess.Paths
                                    .Where(m => m.From == flowContext.CurrentActivityId).ToArray(),
                PreviousActivity = previousAct == null ? Guid.Empty : previousAct.ActivetyId
            };
            return context;
        }
        /// <summary>
        /// 执行活动
        /// </summary>
        /// <param name="flowContext">
        /// 流程流转上下文
        /// </param>
        /// <param name="previousAct">
        /// 表示该活动的前一个活动实例
        /// </param>
        /// <returns>操作结果</returns>
        private OperateResult ExecuteActivity(ProcessFlowContext flowContext, ActivityInstance previousAct = null)
        {
            //判断活动状态
            if (flowContext.CurrentActivityInstance.State == ActivityInstanceState.Completed) return new OperateResult() { ResultCode = 0x100301, Message = "指定活动已执行完毕，无法继续执行！" };
            ApplicationInvokeContext context = this.CreateApplicationInvokeContext(flowContext, previousAct);
            //执行应用程序
            OperateResult executeAppRes = ExecuteApplication(flowContext, context);
            if (executeAppRes.ResultCode != 200) { return new OperateResult() { ResultCode = 0x100302, Message = "执行应用程序失败！", InnerResult = executeAppRes }; }
            return OperateResult.SuccessResult();
        }
        /// <summary>
        /// 执行应用程序
        /// </summary>
        /// <param name="flowContext">
        /// 流程流转上下文
        /// </param>
        /// <param name="isSubmitTask">
        /// 表示当前的调用是否由任务提交函数发起
        /// </param>
        /// <param name="submitTask">
        /// 如果当前电泳是由任务提交函数发起，该参数会传递提交的任务实例
        /// </param>
        /// <param name="invokeContext">
        /// 应用程序调用上下文
        /// </param>
        /// <returns>操作结果</returns>
        private OperateResult ExecuteApplication(ProcessFlowContext flowContext, ApplicationInvokeContext invokeContext, bool isSubmitTask = false, WorkFlowTask submitTask = null)
        {
            //取得应用程序
            IWorkFlowApplication app = this.Components.ApplicationPool.GetApplication(flowContext.CurrentProcess.Identity, flowContext.CurrentActivity.Type);
            if (app == null) return new OperateResult() { ResultCode = 0x100401, Message = "未绑定类型为 " + flowContext.CurrentActivity.Type + " 的活动应用程序！" };

            try
            {
                //如果不是任务提交
                if (!isSubmitTask)
                {
                    ApplicationExecuteResult res = null;
                    //执行执行函数
                    res = app.Execute(invokeContext);
                    //处理执行函数执行结果
                    OperateResult processRes = ProcessAppExecuteResult(invokeContext, flowContext, app, res);
                    if (processRes.ResultCode != 200) return new OperateResult() { ResultCode = 0x100402, Message = "处理应用程序执行结果失败！", InnerResult = processRes };
                    return OperateResult.SuccessResult();
                }
                else
                {
                    //如果是任务提交，则执行提交函数
                    TaskSubmitResult res = app.ProcessTaskSubmit(invokeContext, submitTask);
                    //处理提交函数执行结果
                    OperateResult processRes = ProcessTaskSubmitResult(invokeContext, flowContext, app, submitTask, res);
                    if (processRes.ResultCode != 200) return new OperateResult() { ResultCode = 0x100402, Message = "处理应用程序执行结果失败！", InnerResult = processRes };
                    return OperateResult.SuccessResult();
                }
            }
            catch (Exception ex)
            {
                return new OperateResult() { ResultCode = 0x100401, Message = "应用程序调用出错：" + ex.Message };
            }

        }
        /// <summary>
        /// 终止流程实例
        /// </summary>
        /// <param name="flowContext">
        /// 流程流转上下文
        /// </param>
        /// <param name="message">
        /// 终止信息
        /// </param>
        /// <returns>操作结果</returns>
        private OperateResult TerminateProcessInstance(ProcessFlowContext flowContext, string message)
        {
            bool isUpdateSuccess = this.Components.ProcessInstanceProvider.UpdateState(flowContext.CurrentProcessInstanceId, ProcessInstanceState.Terminated);
            isUpdateSuccess &= this.Components.ProcessInstanceProvider.UpdateTag(flowContext.CurrentProcessInstanceId, message);
            if (!isUpdateSuccess) return new OperateResult() { ResultCode = 0x100504, Message = "终止流程失败，更新流程实例失败！" };
            //TODO:终止流程的相关操作

            return OperateResult.SuccessResult();
        }
        /// <summary>
        /// 处理应用程序执行结果
        /// </summary>
        /// <param name="invokeContext">
        /// 应用程序调用上下文
        /// </param>
        /// <param name="flowContext">
        /// 流程流转上下文
        /// </param>
        /// <param name="app">
        /// 调用的应用程序
        /// </param>
        /// <param name="res">
        /// 应用程序执行结果
        /// </param>
        /// <returns>
        /// 操作结果
        /// </returns>
        private OperateResult ProcessAppExecuteResult(ApplicationInvokeContext invokeContext, ProcessFlowContext flowContext, IWorkFlowApplication app, ApplicationExecuteResult res)
        {
            //如果应用程序为流程分配了任务
            if (res.SendTasks != null && res.SendTasks.Length > 0)
            {
                //发送任务给指定用户
                foreach (var tsk in res.SendTasks)
                {
                    OperateResult sendRes = SendTask(flowContext, tsk);
                    if (sendRes.ResultCode != 200)
                    {
                        return new OperateResult() { ResultCode = 0x100501, Message = "发送任务失败！" };
                    }
                }
                //更新活动状态
                bool isUpdateSuccess = this.Components.ActivityInstanceProvider.UpdateState(flowContext.CurrentActivityInstanceId, ActivityInstanceState.Active);
                if (!isUpdateSuccess) return new OperateResult() { ResultCode = 0x100502, Message = "活动状态更新失败！" };
                return OperateResult.SuccessResult();
            }
            //更新活动数据
            this.Components.ActivityInstanceProvider.UpdateData(flowContext.CurrentActivityInstanceId, res.ApplicationData);
            OperateResult flowResult = this.PrepareFlowTo(flowContext, res);

            if (flowResult.ResultCode != 200)
            {
                return new OperateResult() { ResultCode = 0x100503, Message = "活动流转失败！", InnerResult = flowResult };
            }
            return OperateResult.SuccessResult();
        }
        /// <summary>
        /// 处理任务提交结果
        /// </summary>
        /// <param name="invokeContext">
        /// 应用程序调用上下文
        /// </param>
        /// <param name="flowContext">
        /// 流程流转上下文
        /// </param>
        /// <param name="app">
        /// 调用的应用程序
        /// </param>
        /// <param name="task">
        /// 提交的任务
        /// </param>
        /// <param name="res">
        /// 任务提交结果
        /// </param>
        /// <returns>
        /// 操作结果
        /// </returns>
        public OperateResult ProcessTaskSubmitResult(ApplicationInvokeContext invokeContext, ProcessFlowContext flowContext, IWorkFlowApplication app, WorkFlowTask task, TaskSubmitResult res)
        {
            //如果任务提交没有被接受
            if (!res.IsAccept)
            {
                return new OperateResult()
                {
                    ResultCode = 0x100901,
                    Message = "任务提交请求被拒绝：" + res.Message
                };
            }

            OperateResult flowResult = this.PrepareFlowTo(flowContext, res);
            if (flowResult.ResultCode != 200)
            {
                return new OperateResult() { ResultCode = 0x100902, Message = "活动流转失败！", InnerResult = flowResult };
            }
            //更新任务状态
            bool saveStateResult = this.Components.WorkFlowTaskProvider.UpdateState(task.Identity, WorkFlowTaskState.Processed, "任务已处理");
            if (!saveStateResult) return new OperateResult() { ResultCode = 0x100903, Message = "更新任务状态失败！" };
            //将任务提交信息记录到步骤信息中
            flowContext.CurrentFlowSetp.Tag = "任务提交消息：" + res.Message;
            return OperateResult.SuccessResult();
        }
        /// <summary>
        /// 流转前的预处理工作
        /// </summary>
        /// <param name="flowContext">
        /// 引擎流转上下文
        /// </param>
        /// <param name="res">
        /// 支持流传的应用程序处理结果
        /// </param>
        /// <returns>
        /// 操作结果
        /// </returns>
        private OperateResult PrepareFlowTo(ProcessFlowContext flowContext, IFlowableResult res)
        {
            //流转
            if (res.NextActivityIds != null)
            {
                foreach (var nextActivityId in res.NextActivityIds)
                {
                    OperateResult flowToResult = this.FlowTo(flowContext, nextActivityId, res.NextActivityEnterData);
                    if (flowToResult.ResultCode != 200)
                    {
                        OperateResult terminateRes = this.TerminateProcessInstance(flowContext, flowToResult.Message);
                        if (terminateRes.ResultCode != 200) return new OperateResult() { ResultCode = 0x100801, Message = "终止流程失败！", InnerResult = terminateRes };
                        return new OperateResult()
                        {
                            ResultCode = 0x100802,
                            Message = "流转至下个活动失败！活动ID：" + nextActivityId,
                            InnerResult = flowToResult
                        };

                    };
                }
                return OperateResult.SuccessResult();
            }
            //如果应用程序未指定接下来的活动，但是当前活动存在后续节点，则标记流程为中断状态
            if (flowContext.CurrentProcess.Paths.FirstOrDefault(m => m.From == flowContext.CurrentActivityId) != null)
            {
                OperateResult terminateRes = this.TerminateProcessInstance(flowContext, "流程异常终止，请联系系统管理员");
                if (terminateRes.ResultCode != 200) return new OperateResult() { ResultCode = 0x100803, Message = "终止流程失败！", InnerResult = terminateRes };
                //向用户发送通知
                NotificationCatalog catalog = this.catInfoFactory.CreateCatalog(flowContext.UserId);
                NotificationManager.Default.SendNotification(catalog, "流程被终止", "流程" + flowContext.CurrentProcess.Name +
                    "(" + flowContext.CurrentProcessInstanceId +
                    ")被异常终止，请联系管理员处理！");
                return OperateResult.SuccessResult();
            }
            //如果应用程序未指定接下来的活动，并且当前活动不存在后续节点，则标记为完成状态
            else
            {
                bool isUpdateSuccess = this.Components.ProcessInstanceProvider.UpdateState(flowContext.CurrentProcessInstanceId, ProcessInstanceState.Completed);
                NotificationCatalog catalog = this.catInfoFactory.CreateCatalog(flowContext.UserId);
                if (!isUpdateSuccess)
                {
                    //向用户发送通知
                    NotificationManager.Default.SendNotification(catalog, "流程未正常完成", "流程" + flowContext.CurrentProcess.Name +
                        "(" + flowContext.CurrentProcessInstanceId +
                        ")未正常完成，请联系管理员处理！");
                    return new OperateResult() { ResultCode = 0x100804, Message = "完成流程失败，更新流程实例失败！" };
                }
                //向用户发送通知
                NotificationManager.Default.SendNotification(catalog, "流程已完成", "流程" + flowContext.CurrentProcess.Name +
                    "(" + flowContext.CurrentProcessInstanceId +
                    ")已成功完成。");
                //TODO完成流程的回收操作
                return OperateResult.SuccessResult();
            }
        }
        /// <summary>
        /// 发送任务
        /// </summary>
        /// <param name="flowContext">
        /// 引擎流转上下文
        /// </param>
        /// <param name="tsk">
        /// 要发送的任务
        /// </param>
        /// <returns>
        /// 操作结果
        /// </returns>
        private OperateResult SendTask(ProcessFlowContext flowContext, WorkFlowTask tsk)
        {
            //设定任务相关信息
            tsk.Sender = flowContext.UserId;
            tsk.CurrentActivity = flowContext.CurrentActivityId;
            tsk.CurrentActivityInstance = flowContext.CurrentActivityInstanceId;
            tsk.CurrentProcess = flowContext.CurrentProcessId;
            tsk.CurrentProcessInstance = flowContext.CurrentProcessInstanceId;
            tsk.SendTime = DateTime.Now;
            tsk.State = WorkFlowTaskState.Created;
            tsk.CurrentSetpId = flowContext.CurrentFlowSetpId;
            if (tsk.SendData == null)
            {
                tsk.SendData = new Dictionary<string, object>();
            }
            tsk.SendData[SystemTaskDataKey.UserFormId] = flowContext.CurrentProcessInstance.EnterData.FirstOrDefault(m => m.Key == SystemDataSlots.ProcessEnterFormDataSlotID).Value;
            //发送任务
            return WorkFlowTaskManager.Default.SendTask(tsk);

        }
        /// <summary>
        /// 提交任务
        /// </summary>
        /// <param name="tsk">
        /// 要提交的任务
        /// </param>
        /// <param name="flowContext">
        /// 引擎流转上下文
        /// </param>
        /// <returns>
        /// 操作结果
        /// </returns>
        private OperateResult SubmitTask(ProcessFlowContext flowContext, WorkFlowTask tsk)
        {
            //判断活动状态
            if (flowContext.CurrentActivityInstance.State != ActivityInstanceState.Active) return new OperateResult() { ResultCode = 0x101001, Message = "根据活动的状态，引擎拒绝提交任务！" };
            ApplicationInvokeContext context = this.CreateApplicationInvokeContext(flowContext);
            //执行应用程序
            OperateResult executeAppRes = ExecuteApplication(flowContext, context, true, tsk);
            if (executeAppRes.ResultCode != 200) { return new OperateResult() { ResultCode = 0x101002, Message = "执行应用程序失败！", InnerResult = executeAppRes }; }
            return OperateResult.SuccessResult();
        }
        /// <summary>
        /// 将当前流程流转到指定活动
        /// </summary>
        /// <param name="flowContext">
        /// 引擎流转上下文
        /// </param>
        /// <param name="nextActId">
        /// 下一个流程的ID
        /// </param>
        /// <param name="flowData">
        /// 流转数据
        /// </param>
        /// <returns>
        /// 操作结果
        /// </returns>
        private OperateResult FlowTo(ProcessFlowContext flowContext, Guid nextActId, KeyValuePair<Guid, Object>[] flowData)
        {
            //取得接下来的路径列表
            FlowPath[] paths = flowContext.CurrentProcess.Paths.Where(m => m.From == flowContext.CurrentActivityId).ToArray();
            FlowPath path = paths.FirstOrDefault(m => m.To == nextActId);
            if (path == null)
            {
                return new OperateResult() { ResultCode = 0x100701, Message = "流程流转违规！" };
            }
            //取得接下来的活动
            Activity nextActivity = flowContext.CurrentProcess.Activitys.FirstOrDefault(m => m.Identity == nextActId);
            if (nextActivity == null) return new OperateResult() { ResultCode = 0x100702, Message = "目标活动不存在！" };
            //记录流程步骤
            FlowSetp newSetp = this.Components.FlowSetpProvider.Create();
            newSetp.ProcessInstanceId = flowContext.CurrentProcessInstanceId;
            flowContext.CurrentFlowSetp = newSetp; //绑定步骤
            this.RecordFrom(flowContext);  //记录起始步骤
            bool isAddSetpSuccess = this.Components.FlowSetpProvider.Add(newSetp);
            if (!isAddSetpSuccess) return new OperateResult() { ResultCode = 0x100703, Message = "新建步骤失败！" };
            //更新流程状态
            bool isUpdateSuccess = this.Components.ProcessInstanceProvider.UpdateState(flowContext.CurrentProcessInstanceId, ProcessInstanceState.Active);
            if (!isUpdateSuccess) return new OperateResult() { ResultCode = 0x100704, Message = "更新流程实例失败！" };
            //进入活动
            OperateResult enterActRes = EnterActivity(flowContext, nextActivity, flowData, flowContext.CurrentActivityInstance);
            if (enterActRes.ResultCode != 200) return new OperateResult() { ResultCode = 0x100705, Message = "进入目标活动失败！", InnerResult = enterActRes };
            //完成流转
            return OperateResult.SuccessResult();
        }


        static WorkFlowEngine()
        {
            Default = new WorkFlowEngine();
        }
    }
}
